package cn.datawin.task;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.datawin.cotask.client.ClientPool;
import cn.datawin.spider.httputil.HttpRequest;
import cn.datawin.spider.httputil.HttpRequest.Method;
import cn.datawin.spider.httputil.HttpService;
import cn.datawin.spider.page.Page;
import cn.datawin.spider.pipeline.PipeLine;
import cn.datawin.spider.processor.Processor;
import cn.datawin.spider.scheduler.PageQueue;
import cn.datawin.task.page.Taskpage;
import cn.datawin.task.util.HttpUtil;
import cn.datawin.task.util.PaserUtil;
import cn.datawin.task.util.SpiderUtil;
import cn.datawin.task.util.TaskUtil;

public class PrepareTask implements Runnable{
	public static PageQueue pageQueue = new PageQueue();
	
	private String workbeach;
	private String state;
	private boolean stop = false;
    private List<Task> tasks=new ArrayList<Task>();
    private Statistic statistic;
	
	
	public Statistic getStatistic() {
		return statistic;
	}

	public void setStatistic(Statistic statistic) {
		this.statistic = statistic;
	}
    
	public PrepareTask() {
	}
	
	public PrepareTask(String workbeach, String state) {
		super();
		this.workbeach = workbeach;
		this.state = state;
	}


	void offerTask() throws Exception {
		if(tasks.size()==0){
			tasks = PaserUtil.dboToTask(TaskUtil.gettask(workbeach, state, Config.apps.get("getTaskNum")));
			Statistic.getInstance().setTasks(tasks);
			while(tasks.size()>0){
				Task task = tasks.remove(0);
				if(task.isBranch()){
					branchTask(task);
					continue;
				}else{
					Page page = task2page(task);
					pageQueue.offer(page);
				}
			}
		}else{
			while(tasks.size()>0){
				Task task = tasks.remove(0);
				if(task.isBranch()){
					branchTask(task);
					continue;
				}else{
					Page page = task2page(task);
					pageQueue.offer(page);
				}
			}
		}
	}

	
	Page task2page(Task task) {

		Page page = new Taskpage();
		Processor processor = SpiderUtil.getProcessor(task.getProcessor());
		PipeLine pipeLine = SpiderUtil.getPipeLine(task.getProcessor());
		processor.setTask(task);
		page.setProcessor(processor);
		page.setPipeLine(pipeLine);
		HttpService httpservice = HttpUtil.getHttpClient();
		if(task.getHttpClientid()!= null&&!task.getHttpClientid().isEmpty()){
			httpservice = ClientPool.get(task.getHttpClientid());
		}
		page.setHttpService(httpservice);
		HttpRequest req = new HttpRequest(task.getUrl());
		Rule rule = new Rule(task.currentRule());
		req.setCharset(rule.getCharset());
		req.setCookies(task.getCookie());
		req.setConnectTimeout(6000);
		req.setReadTimeout(6000);
		req.setMethod(rule.getMethod().equalsIgnoreCase("post") ? Method.post : Method.get);
		req.setHeaders(task.getHeader());
		req.setPostParams(rule.getData());
		page.setHttpRequest(req);
		return page;

	}
	

	void branchTask(Task task){
		List<Map<String, Object>> rules =  task.getRules();
		for(final Map<String, Object> map: rules){
			List<Map<String, Object>> rule = new ArrayList<Map<String,Object>>(){
				{add(map);}
			};
			
			task.setProcessor((String)rule.get(0).get("type"));
			task.setClient(task.getClient());
			try {
				Map<String, String> obj = new HashMap<String, String>();
				obj.put("serializeList", HttpUtil.serialize(task));
				obj.put("rules", HttpUtil.serialize(rule));
				TaskUtil.addtask(obj);
			} catch (Exception e) {
				e.printStackTrace();
			}finally{
				try {
					Statistic.getInstance().addCount(task);
				} catch (Exception e1) {
					e1.printStackTrace();
				}
				String flag=Config.apps.get("isReport");
				if("true".equals(flag)){
					//更改对应task状态为2
					try {
						comptask(task.getId());
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}
		
	}

	public String comptask(String taskid) throws Exception{
		String s=TaskUtil.comptask(taskid);
		if("1".equals(s)){
			return s;
		}else{
			return comptask(taskid);
		}
	}
	
	int times = 0;
	@Override
	public void run() {
		while(!stop){
			try{
				if(pageQueue.size()==0){
					offerTask();
				}
				try{
					if(times==0){
						TaskUtil.updateclient(Config.apps.get("workbeach"),0+"");
					}else if(times%6==0){
						TaskUtil.updateclient(Config.apps.get("workbeach"),Statistic.getInstance().getCount()+"");
					}
					times++;
					Thread.sleep(10000);
				}catch(Exception e){}
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}
	
	public boolean isStop() {
		return stop;
	}

	
	public List<Task> getTasks() {
		return tasks;
	}

	public void setTasks(List<Task> tasks) {
		this.tasks.addAll(tasks);
	}

	public void setStop(boolean stop) {
		this.stop = stop;
	}
	
	public void start(){
		new Thread(this).start();
	}
}
